/*
 * Copyright (c) 2013-2018 上海汇数数据. All rights reserved.
 * @(#) OprMode.java 2018-08-06 17:26
 */

package cn.jh.common.core.crypto;

import org.jetbrains.annotations.NotNull;


/**
 * 密码学中，分组（block）密码的工作模式（[mode of operation](http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation)）枚举
 *
 * @author Fuchun
 * @since 1.0
 */
public enum OprMode {

    /**
     * 不使用任何模式。
     */
    NONE,

    /**
     * 密码分组链接模式 ([Cipher-block chaining](https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F#.E5.AF.86.E7.A0.81.E5.9D.97.E9.93.BE.E6.8E.A5.EF.BC.88CBC.EF.BC.89))。
     */
    CBC,

    /**
     * 电子密码本（[Electronic codebook，ECB](https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F#.E7.94.B5.E5.AD.90.E5.AF.86.E7.A0.81.E6.9C.AC.EF.BC.88ECB.EF.BC.89)）模式。
     * 这个不是一个安全可靠的模式，对外数据中坚决不要使用。
     */
    ECB,

    /**
     * 填充密码块链接（[PCBC，Propagating cipher-block chaining](https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F#.E5.A1.AB.E5.85.85.E5.AF.86.E7.A0.81.E5.9D.97.E9.93.BE.E6.8E.A5.EF.BC.88PCBC.EF.BC.89)）
     */
    PCBC,

    /**
     * 密文反馈（[CFB，Cipher feedback](https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F#.E5.AF.86.E6.96.87.E5.8F.8D.E9.A6.88.EF.BC.88CFB.EF.BC.89)）模式。
     */
    CFB,

    /**
     * 输出反馈模式（[Output feedback, OFB](https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F#.E8.BE.93.E5.87.BA.E5.8F.8D.E9.A6.88.EF.BC.88OFB.EF.BC.89)）
     */
    OFB,

    /**
     * CTR模式（[Counter mode，CM](https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F#.E8.AE.A1.E6.95.B0.E5.99.A8.E6.A8.A1.E5.BC.8F.EF.BC.88CTR.EF.BC.89)
     * 也被称为ICM模式（Integer Counter Mode，整数计数模式）和SIC模式（Segmented Integer Counter）。
     */
    CTR
    ;

    @NotNull
    public static OprMode forString(String name) {
        String nameUpper;
        if (name == null || (nameUpper = name.trim().toUpperCase()).isEmpty()) return NONE;
        for (OprMode mode : values()) {
            if (nameUpper.equals(mode.name())) {
                return mode;
            }
        }
        return NONE;
    }
}
